//! WebAssembly module for AES decryption of reward data

use wasm_bindgen::prelude::*;
use aes::Aes256;
use web_sys::console;
use base64::engine::general_purpose;
use base64::Engine as _;
use aes_gcm::{Aes256Gcm, Key, Nonce};
use aes_gcm::aead::{Aead, KeyInit};

// For better error messages in case of panics
#[cfg(feature = "console_error_panic_hook")]
pub fn init_panic_hook() {
    console_error_panic_hook::set_once();
}

// Use `wee_alloc` as the global allocator to reduce code size
#[cfg(feature = "wee_alloc")]
#[global_allocator]
static ALLOC: wee_alloc::WeeAlloc = wee_alloc::WeeAlloc::INIT;



#[wasm_bindgen]
pub fn decrypt_reward_data(email: &str, timestamp: &str, encrypted_str: &str) -> Result<String, JsValue> {
    #[cfg(feature = "console_error_panic_hook")]
    console_error_panic_hook::set_once();

    // 打印传入的三个值
    // console::log_1(&JsValue::from_str(&format!("传入的三个值: email: {}, timestamp: {}, encrypted_str: {}", email, timestamp, encrypted_str)));
    
    // 生成密钥：email+timestamp，补0到31字节，最后一位为'1'，总共32字节
    let mut key_bytes = Vec::with_capacity(32);
    key_bytes.extend_from_slice(email.as_bytes());
    key_bytes.extend_from_slice(timestamp.as_bytes());
    while key_bytes.len() < 31 {
        key_bytes.push(b'0');
    }
    key_bytes.truncate(31); // 防止超长
    key_bytes.push(b'1');
    let key = Key::<Aes256Gcm>::from_slice(&key_bytes);

    // 新增：打印string形式的密钥
    let key_str = match std::str::from_utf8(&key_bytes) {
        Ok(s) => s.to_string(),
        Err(_) => String::from_utf8_lossy(&key_bytes).to_string(),
    };
    // console::log_1(&JsValue::from_str(&format!("WASM解密端密钥(string): {}", key_str)));

    // base64 解码
    let encrypted_data = general_purpose::STANDARD
        .decode(encrypted_str)
        .map_err(|e| JsValue::from_str(&format!("Base64 decode error: {}", e)))?;

    // nonce 长度为 12 字节
    if encrypted_data.len() < 12 {
        return Err(JsValue::from_str("Invalid encrypted data: too short to contain nonce"));
    }
    let nonce = Nonce::from_slice(&encrypted_data[..12]);
    let ciphertext = &encrypted_data[12..];

    let cipher = Aes256Gcm::new(key);
    let plaintext = cipher.decrypt(nonce, ciphertext)
        .map_err(|e| JsValue::from_str(&format!("Decryption error: {}", e)))?;

    String::from_utf8(plaintext)
        .map_err(|e| JsValue::from_str(&format!("UTF-8 conversion error: {}", e)))
}

#[wasm_bindgen]
pub fn init() {
    #[cfg(feature = "console_error_panic_hook")]
    console_error_panic_hook::set_once();
}

